/** 
 * BatsmanValidators.java Created by iweerarathna on Sep 1, 2011.
 * 
 * Copyright (c) 2011 Virtusa Corporation. All Rights Reserved.<br><br>. 
 * 
 */
package org.uim.cricket.analyzer.validate.impl;

import java.util.List;
import java.util.Map;

import org.uim.cricket.analyzer.validate.VLogger;
import org.uim.cricket.analyzer.validate.ValidatableMatch;
import org.uim.cricket.entities.MatchPlayer;
import org.uim.cricket.entities.aggr.SingleInning;
import org.uim.cricket.entities.batting.BatsmanStatistics;
import org.uim.cricket.entities.batting.BattingInning;
import org.uim.cricket.entities.batting.OutTypes;
import org.uim.cricket.entities.match.CricketMatch;

/**
 * TODO Class description goes here.
 * @version 
 * @author iweerarathna
 */
public class BatsmanValidators implements ValidatableMatch {

    @Override
    public void processValidation(CricketMatch match, Map<String, List<MatchPlayer>> players) throws Exception {
    	
        if (match.getInnings() == null) return;
        
        SingleInning[] inns = match.getInnings();
        
        for (int i=0; i<inns.length; i++) {
        	if (inns[i] == null) continue;
        	
            if (inns[i].getBatInnings() != null) {
                this.processBattings(inns[i].getBatInnings(), match, (i+1));
            }
        }

    }

    private void processBattings(List<BattingInning> bats, CricketMatch match, int inning) throws Exception {
        
        SingleInning inn = match.getInnings()[inning - 1];
        int totals = 0;
        
        for (int i=0; i<bats.size(); i++) {
            BattingInning bat = bats.get(i);
            if (bat == null) continue;
            
            BatsmanStatistics stats = bat.getStatistics();
            if (stats == null) {
                if  (bat.getOutDetails() == null || bat.getOutDetails().getOutType() == OutTypes.DID_NOT_BAT) {
                    continue;
                } else {
                    VLogger.warn(bat.getBatsman().getTitleName() + " hasn't any statistic records, but his outtype is different!");
                    VLogger.warn("[OutType: " + bat.getOutDetails().getOutType().toString() + "]");
                }
            }
            
            if (stats.getRuns() < (stats.getFours()*4 + stats.getSixes()*6)) {
                VLogger.warn(bat.getBatsman().getTitleName() + "'s runs are lower than his boundaries.");
                VLogger.info("[Runs: " + stats.getRuns() + ", " + stats.getFours() + "x4s + " +
                                    stats.getSixes() + "x6s]");
            }
            
            if (stats.getRuns() >= 0) {
                totals += stats.getRuns();
            }
            
        }
       
        if (inn.getTotals() == null) {
            
            VLogger.warn("No total record exists in inning " + inning);
        
        } else {
            
            if (inn.getExtras() != null) {
                totals += inn.getExtras().totalExtras();
            }
            
            if (totals != inn.getTotals().getRuns()) {
                VLogger.error("Total runs are not equal to batsmen plus extras!");
                VLogger.error("[Total-Runs: " + inn.getTotals().getRuns() + ", Total-Scored: " +
                        totals + "]");
            }
            
        }
        
    }
    
    
}
